package com.trestristesmicos.anahuac.tools;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;
import android.util.Log;

public class DataXmlExporter {

		   private static final String DATASUBDIRECTORY = "Anahuacdata";

		   private SQLiteDatabase db;
		   private XmlBuilder xmlBuilder;

		   public DataXmlExporter(SQLiteDatabase db) {
		      this.db = db;
		   }

		   public void export(String dbName, String exportFileNamePrefix) throws IOException {
		      Log.i("DataXmlExporter", "exporting database - " + dbName + " exportFileNamePrefix=" + exportFileNamePrefix);

		      this.xmlBuilder = new XmlBuilder();
		      this.xmlBuilder.start(dbName);

		      // get the tables
		      String sql = "select * from sqlite_master";
		      Cursor c = this.db.rawQuery(sql, new String[0]);
		      Log.d("DataXmlExporter", "select * from sqlite_master, cur size " + c.getCount());
		      if (c.moveToFirst()) {
		         do {
		            String tableName = c.getString(c.getColumnIndex("name"));
		            Log.d("DataXmlExporter", "table name " + tableName);

		            // skip metadata, sequence, and uidx (unique indexes)
		            if (!tableName.equals("android_metadata") && !tableName.equals("sqlite_sequence")
		                     && !tableName.startsWith("uidx")) {
		               this.exportTable(tableName);
		            }
		         } while (c.moveToNext());
		      }
		      String xmlString = this.xmlBuilder.end();
		      this.writeToFile(xmlString, exportFileNamePrefix + ".xml");
		      Log.i("DataXmlExporter", "exporting database complete");
		   }

		   private void exportTable(final String tableName) throws IOException {
		      Log.d("DataXmlExporter", "exporting table - " + tableName);
		      this.xmlBuilder.openTable(tableName);
		      String sql = "select * from " + tableName;
		      Cursor c = this.db.rawQuery(sql, new String[0]);
		      if (c.moveToFirst()) {
		         int cols = c.getColumnCount();
		         do {
		            this.xmlBuilder.openRow();
		            for (int i = 0; i < cols; i++) {
		               this.xmlBuilder.addColumn(c.getColumnName(i), c.getString(i));
		            }
		            this.xmlBuilder.closeRow();
		         } while (c.moveToNext());
		      }
		      c.close();
		      this.xmlBuilder.closeTable(tableName);
		   }

		   private void writeToFile(String xmlString, String exportFileName) throws IOException {
		      File dir = new File(Environment.getExternalStorageDirectory(), DATASUBDIRECTORY);
		      if (!dir.exists()) {
		         dir.mkdirs();
		      }
		      File file = new File(dir, exportFileName);
		      file.createNewFile();

		      ByteBuffer buff = ByteBuffer.wrap(xmlString.getBytes());
		      FileChannel channel = new FileOutputStream(file).getChannel();
		      try {
		         channel.write(buff);
		      } finally {
		         if (channel != null)
		            channel.close();
		      }
		   }

		   /**
		    * 
		    * 
		    *
		    * @author ccollins
		    *
		    */
		   class XmlBuilder {
		      private static final String OPEN_XML_STANZA = "<?xml version='1.0' encoding= 'UTF-8' standalone='yes' ?>";
		      private static final String OPEN_WITHOUT_TICK = "<";
		      private static final String OPEN_CLOSE_WITHOUT_TICK = "</";
		      private static final String CLOSE_WITHOUT_TICK = ">";		     
		      private static final String DB_CLOSE = "";
		      private static final String TABLE_OPEN = "<";		    
		      private static final String ROW_OPEN = "<row>";
		      private static final String ROW_CLOSE = "</row>";
		     
		      private final StringBuilder sb;

		      public XmlBuilder() throws IOException {
		         this.sb = new StringBuilder();
		      }

		      void start(String dbName) {
		         this.sb.append(OPEN_XML_STANZA);
		         // this.sb.append(DB_OPEN + dbName + CLOSE_WITH_TICK);
		      }

		      String end() throws IOException {
		         this.sb.append(DB_CLOSE);
		         return this.sb.toString();
		      }

		      void openTable(String tableName) {
		         this.sb.append(TABLE_OPEN + tableName + CLOSE_WITHOUT_TICK);
		      }

		      void closeTable(String tableName) {
		    	  this.sb.append(OPEN_CLOSE_WITHOUT_TICK + tableName + CLOSE_WITHOUT_TICK);
		      }

		      void openRow() {
		         this.sb.append(ROW_OPEN);
		      }

		      void closeRow() {
		         this.sb.append(ROW_CLOSE);
		      }

		      void addColumn(final String name, final String val) throws IOException {
		         this.sb.append(OPEN_WITHOUT_TICK + name + CLOSE_WITHOUT_TICK + val + OPEN_CLOSE_WITHOUT_TICK+ name + CLOSE_WITHOUT_TICK);
		      }
	   }
}
